﻿using Bikiball.Core;
using Bikiball.Game;
using Bikiball.Graphic.Constructor;
using Bikiball.Graphic.Vextex;
using Bikiball.Physic;
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.Toolkit;
using SharpDX.Toolkit.Content;
using SharpDX.Toolkit.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SamplerState = SharpDX.Toolkit.Graphics.SamplerState;
using RasterizerState = SharpDX.Toolkit.Graphics.RasterizerState;
using BikiBall.Input;

namespace Bikiball.Graphic
{
    public class GraphicEngine : Engine
    {
        private static int i = 0;
        public static GraphicsDevice GraphicsDevice { get; private set; }
        public static ContentManager Content;
        public Matrix Projection =  Matrix.Zero;
        DepthStencilBuffer depthStencilBuffer;
        RasterizerState rasteState;

        public GraphicEngine(GraphicsDevice graphicDevice)
        {
            GraphicsDevice = graphicDevice;
        }

        public void Init()
        {
            Projection = Matrix.PerspectiveFovRH((float)Math.PI / 4.0f, (float)(GraphicEngine.GraphicsDevice.BackBuffer).Width / (GraphicEngine.GraphicsDevice.BackBuffer).Height, 0.1f, 100.0f);
#warning Trop lent et je sais pas pourquoi...
            depthStencilBuffer = DepthStencilBuffer.New(GraphicsDevice, GraphicsDevice.BackBuffer.Width, GraphicsDevice.BackBuffer.Height, DepthFormat.Depth16);
            //GraphicsDevice.Presenter.DepthStencilBuffer = depthStencilBuffer;
            GraphicsDevice.SetDepthStencilState(GraphicsDevice.DepthStencilStates.Default);
        }

        public void LoadContent(ContentManager content)
        {
            Content = content;
            Map3DConstructor.LoadContent();
            Map2DConstructor.LoadContent();
            RasterizerStateDescription defRast = RasterizerStateDescription.Default();
            defRast.FillMode = FillMode.Wireframe;
            rasteState = RasterizerState.New(GraphicsDevice, defRast);
        }

        public void RenderToDevice(List<BikiObject> gameObjects, Camera camera, GameTime gameTime)
        {
            GraphicsDevice.SetRenderTargets(depthStencilBuffer, GraphicsDevice.BackBuffer);
            if (InputEngine.IsTapped)
                GraphicsDevice.SetRasterizerState(rasteState);
            GraphicsDevice.Clear(new Color4(0/255.0f, 66/255.0f, 99/255.0f, 0.0f));
            GraphicsDevice.Clear(depthStencilBuffer, DepthStencilClearFlags.Depth, 1.0f, 0);
            //GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1, 0);
            Matrix view = Matrix.LookAtRH(new Vector3(camera.Position.X + 0.0001f, camera.Position.Y, camera.Position.Z), new Vector3(camera.Position.X, 0, camera.Position.Z), Vector3.UnitY);
            foreach (BikiObject gameObject in gameObjects.Where(x=> x.HasProperty<GraphicProperty>()))
            {
                GraphicProperty graphProp;
                if (InputEngine.IsHold)
                    graphProp = gameObject.GetProperties<MapGraphicProperty>();
                else
                    graphProp = gameObject.GetProperties<GraphicProperty>();
                PhysicProperty physProp = gameObject.GetProperties<PhysicProperty>();
                Matrix world = Matrix.Scaling(1.0f) * Matrix.Translation(physProp.Position);
                graphProp.Draw(world, view, Projection, gameTime);

            }
        }
    }
}
